package com.kancy.okhttp.client.support;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 动态设置接口请求超时时间
 *
 * @author kancy
 * @date 2020/4/30 23:50
 */
public class OkHttpClientDynamicTimeoutInterceptor implements Interceptor {

    private static final String PARAM_NAME_CONNECT_TIMEOUT = "connectTimeout";
    private static final String PARAM_NAME_READ_TIMEOUT = "readTimeout";
    private static final String PARAM_NAME_WRITE_TIMEOUT = "writeTimeout";
    private static final String PARAM_NAME_READ_WRITE_TIMEOUT = "timeout";

    /**
     * 接口调用拦截
     * @param chain
     * @return
     * @throws IOException
     */
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        // 动态设置连接超时时间
        Integer connectTimeout = getConnectTimeout(chain);
        if (Objects.nonNull(connectTimeout) && connectTimeout > 0){
            chain = chain.withConnectTimeout(connectTimeout, TimeUnit.SECONDS);
        }
        // 动态设置读超时时间
        Integer readTimeout = getReadTimeout(chain);
        if (Objects.nonNull(readTimeout) && readTimeout > 0){
            chain = chain.withReadTimeout(readTimeout, TimeUnit.SECONDS);
        }
        // 动态设置写超时时间
        Integer writeTimeout = getWriteTimeout(chain);
        if (Objects.nonNull(writeTimeout) && writeTimeout > 0){
            chain = chain.withWriteTimeout(writeTimeout, TimeUnit.SECONDS);
        }
        return chain.proceed(request);
    }

    /**
     * 获取连接超时时间，秒
     * @param chain
     * @return
     */
    private Integer getConnectTimeout(Chain chain) {
        return getTimeout(chain, PARAM_NAME_CONNECT_TIMEOUT);
    }

    /**
     * 获取写超时时间，秒
     * @param chain
     * @return
     */
    private Integer getWriteTimeout(Chain chain) {
        Integer writeTimeout = getTimeout(chain, PARAM_NAME_WRITE_TIMEOUT);
        if (Objects.isNull(writeTimeout)){
            return getTimeout(chain, PARAM_NAME_READ_WRITE_TIMEOUT);
        }
        return writeTimeout;
    }

    /**
     * 获取读超时时间，秒
     * @param chain
     * @return
     */
    private Integer getReadTimeout(Chain chain) {
        Integer readTimeout = getTimeout(chain, PARAM_NAME_READ_TIMEOUT);
        if (Objects.isNull(readTimeout)){
            return getTimeout(chain, PARAM_NAME_READ_WRITE_TIMEOUT);
        }
        return readTimeout;
    }

    private Integer getTimeout(Chain chain, String timeoutName) {
        Request request = chain.request();
        String timeout = request.headers().get(timeoutName);
        if (Objects.isNull(timeout)){
            timeout = request.url().queryParameter(timeoutName);
        }
        return castToInteger(timeout);
    }

    /**
     * 字符串转数字
     * @param intString
     * @return
     */
    private Integer castToInteger(String intString) {
        try {
            if (intString == null){
                return null;
            }
            return Integer.valueOf(intString);
        } catch (NumberFormatException e) {
            return null;
        }
    }
}